package com.zzuli.yxypre.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzuli.yxypre.entity.PlayCount;
import com.zzuli.yxypre.entity.Song;
import com.zzuli.yxypre.entity.Top;
import com.zzuli.yxypre.mapper.PlayCountMapper;
import com.zzuli.yxypre.mapper.SongMapper;
import com.zzuli.yxypre.mapper.TopMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;

import static com.zzuli.yxypre.task.TopWeight.*;
import static com.zzuli.yxypre.task.TopWeight.newTimeWeight;

/**
 * 定时任务：更新排行榜
 * @auther pony
 * @create 2023-05-12 14:28
 */
@Component
public class updateTop {
    @Autowired
    private PlayCountMapper playCountMapper;

    @Autowired
    private TopMapper topMapper;

    @Autowired
    private SongMapper songMapper;

    /**
     * 更新飙升榜榜单
     */
//    @Scheduled(cron = "0 0 23 * * ?") // 每天半夜 23 点更新更新数据
    @Scheduled(initialDelay = 1 * 1000, fixedRate=1000*60*60*24*7) //项目启动后1s，执行一次，每隔一周再次执行
    void updateSoar(){
        // 更新前先清空排行榜
        LambdaQueryWrapper<Top> delQw = new LambdaQueryWrapper<>();
        delQw.eq(Top::getType, 1);
        topMapper.delete(delQw);
        //1、获取今日飙升榜前 100 首歌曲 id
        List<PlayCount> soarPlayCountList = playCountMapper
                .getSoarPlayCountList(1);
        for (PlayCount playCount : soarPlayCountList) {
            Integer songId = playCount.getRelevance();
            // 写入 top 表单
            topMapper.insert(new Top(null, songId, 1));
        }
    }

    /**
     * 更新热门榜榜单 每周一 23 点更新
     */
//    @Scheduled(cron = "0 0 23 ? * 1") // 每天半夜 23 点更新更新数据
    @Scheduled(initialDelay = 1 * 1000, fixedRate=1000*60*60*24*7) //项目启动后1s，执行一次，每隔一周再次执行
    void updateHot(){
        // 更新前先清空排行榜
        LambdaQueryWrapper<Top> delQw = new LambdaQueryWrapper<>();
        delQw.eq(Top::getType, 2);
        topMapper.delete(delQw);
        //1、获取所有有月播放量的歌曲
        LambdaQueryWrapper<PlayCount> pcQw = new LambdaQueryWrapper<>();
        pcQw.eq(PlayCount::getType, 1);
        List<PlayCount> playCountList = playCountMapper.selectList(pcQw);
        ArrayList<Song> songList = new ArrayList<>();

        for (PlayCount playCount : playCountList) {
            Integer songId = playCount.getRelevance();
            System.out.println(songId);
            LambdaQueryWrapper<Song> songQw = new LambdaQueryWrapper<>();
            songQw.eq(Song::getSongId, songId);
            Song song = songMapper.selectOne(songQw);
            System.out.println(song);
            Date songTime = song.getSongTime();
            Date date =  new Date();
            int days = differentDays(songTime, date);
            song.setPlayCountWeight(hotPlayCountWeight);
            song.setTimeWeight(hotTimeWeight);
            song.setTime(1.0/days);
            song.setWeekCount(playCount.getWeekCount());
            songList.add(song);
        }
        // 使用 Comparator 比较器排序
        Collections.sort(songList);
        for (int i = 0; i < songList.size(); i++){
            // 排行榜只要前 100 首歌，超出直接跳出循环
            if (i==100){
                break;
            }
            Song song = songList.get(i);
            Integer songId = song.getSongId();
            // 写入 top 表单
            topMapper.insert(new Top(null, songId, 2));
        }
    }

    /**
     * 更新热门榜榜单 每周一 23 点更新
     */
//    @Scheduled(cron = "0 0 23 ? * 1") // 每天半夜 23 点更新更新数据
    @Scheduled(initialDelay = 1 * 1000, fixedRate=1000*60*60*24*7) //项目启动后1s，执行一次，每隔一周再次执行
    void updateNew(){
        // 更新前先清空排行榜
        LambdaQueryWrapper<Top> delQw = new LambdaQueryWrapper<>();
        delQw.eq(Top::getType, 3);
        topMapper.delete(delQw);
        //1、获取所有有月播放量的歌曲
        LambdaQueryWrapper<PlayCount> pcQw = new LambdaQueryWrapper<>();
        pcQw.eq(PlayCount::getType, 1);
        List<PlayCount> playCountList = playCountMapper.selectList(pcQw);
        ArrayList<Song> songList = new ArrayList<>();

        for (PlayCount playCount : playCountList) {
            Integer songId = playCount.getRelevance();
            System.out.println(songId);
            LambdaQueryWrapper<Song> songQw = new LambdaQueryWrapper<>();
            songQw.eq(Song::getSongId, songId);
            Song song = songMapper.selectOne(songQw);
            System.out.println(song);
            Date songTime = song.getSongTime();
            Date date =  new Date();
            int days = differentDays(songTime, date);
            song.setPlayCountWeight(newPlayCountWeight);
            song.setTimeWeight(newTimeWeight);
            song.setTime(1.0/days);
            song.setWeekCount(playCount.getWeekCount());
            songList.add(song);
        }
        // 使用 Comparator 比较器排序
        Collections.sort(songList);
        for (int i = 0; i < songList.size(); i++){
            // 排行榜只要前 100 首歌，超出直接跳出循环
            if (i==100){
                break;
            }
            Song song = songList.get(i);
            Integer songId = song.getSongId();
            // 写入 top 表单
            topMapper.insert(new Top(null, songId, 3));
        }
    }

    // 计算两个日期之间相差的天数
    public static int differentDays(Date date1,Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1= cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if(year1 != year2)   //同一年
        {
            int timeDistance = 0 ;
            for(int i = year1 ; i < year2 ; i ++)
            {
                if(i%4==0 && i%100!=0 || i%400==0)    //闰年
                {
                    timeDistance += 366;
                }
                else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2-day1) ;
        }
        else    //不同年
        {
            System.out.println("判断day2 - day1 : " + (day2-day1));
            return day2-day1;
        }
    }
}
